package cn.terrence.myrpc.common.rpc.server;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

import cn.terrence.myrpc.common.rpc.common.Request;
import cn.terrence.myrpc.common.rpc.log.LogUtils;

/**
 * 请求消息   解码器，实现自定义协议,,,用于服务端
 * 
 * 自定义协议如下 4字节的请求序列号 2字节的请求类型 2字节数据长度 2字节服务调用长度 N字节的服务调用名 2字节请求参数长度 请求参数
 * 其中请求类型为1：服务调用2：心跳包，如果是心跳包的话，只有协议头，也就是【4字节请求序列号，2字节请求类型，2字节数据长度】
 * 
 * @author prestigeding@126.com
 *
 */
public class ServerRequestFrameDecoder extends ByteToMessageDecoder {

	/** 协议头 长度 */
	private static final int HEAD_LENGTH = 8;

	/*
	 * (non-Javadoc)
	 * 
	 * @param ctx Handler执行环境
	 * 
	 * @param in //当前累积缓存区字节
	 * 
	 * @param out //解码后的消息
	 */
	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf in,
			List<Object> out) throws Exception {
		// TODO Auto-generated method stub
		LogUtils.log("ServerRequestFrameDecoder start calling....");
		int r = in.readableBytes();
		LogUtils.log("ServerRequestFrameDecoder 累计缓存去大小：%d", r);
		if (r < HEAD_LENGTH) {
			LogUtils.log("ServerRequestFrameDecoder 当前累积缓存区可读数据长度为%d,小于协议头的长度%d", r, HEAD_LENGTH);
			return;
		}
		int currentReaderIndex = in.readerIndex();
		int requestId = in.getInt(currentReaderIndex);// 0-3
		short requestType = in.getShort(currentReaderIndex + 4);// 4-5
		short contentLength = in.getShort(currentReaderIndex + 6);// 6-7 头部信息共8个字节
		LogUtils.log("ServerRequestFrameDecoder requestId:%d,requestType:%d,contentLength:%d", requestId, requestType, contentLength);
		Request request = null;
		if (requestType == 1) {
			if (r < (HEAD_LENGTH + contentLength)) { // 如果累积缓存区可读容量小于一个请求包的长度，直接返回
				LogUtils.log("ServerRequestFrameDecoder 当前累积缓存区可读数据长度为%d,小于数据报的长度%d", r, HEAD_LENGTH + contentLength);
				return;
			}
			// 否则，直接读取数据
			in.skipBytes(HEAD_LENGTH);// 先跳过协议头信息
			int slen = in.readShort();
			byte[] serviceData = new byte[slen];
			in.readBytes(serviceData, 0, slen);
			short plen = in.readShort();
			byte[] paramsData = new byte[plen];
			in.readBytes(paramsData, 0, plen);
			request = new Request(requestId, requestType,new String(serviceData), new String(paramsData));
			System.out.println(request.getParams()+":"+request.getService());
			out.add(request);
			request.setContentLength(contentLength); //这里，其实上层应用不需要知道请求包的长度，这里属于多于的操作
			LogUtils.log("ServerRequestFrameDecoder 成功从服务端响应中解析出业务包,requestId:%d", requestId);
		} else if (requestType == 2) { // 此处不对请求类型进行校验
			in.skipBytes(HEAD_LENGTH);
			out.add(request = new Request(requestId, requestType));
			request.setContentLength(contentLength); //这里，其实上层应用不需要知道请求包的长度，这里属于多于的操作
			LogUtils.log("ServerRequestFrameDecoder 成功从服务端响应中解析出心跳包,requestId:%d", requestId);
		}
	}
}
